#include <sstream>
#include <sys/stat.h>
#include <boost/lexical_cast.hpp>
#include "FileReader.h"

using namespace kc_sf;

FileReader::FileReader(const std::string &filepath)
: fr_stream(filepath.c_str()), fr_file_size(0)
{
	// czy plik istnieje ?
	struct stat stat_buf;
	if (stat(filepath.c_str(), &stat_buf) != 0)
	{
		throw Error(Error::NO_FILE,
				"Konstruktor w FileReader.cpp: Nie można otworzyć pliku "
						+ filepath + "\n. Czy plik istnieje?");
	}

	if (!fr_stream.is_open())
		throw Error(Error::NO_ACCESS,
				"Konstruktor w FileReader.cpp: Brak dostępu do pliku "
						+ filepath + "\n.");

	fr_stream.seekg(0, std::ios::end);
	fr_file_size = fr_stream.tellg();
	fr_stream.seekg(0, std::ios::beg);
}

FileReader::~FileReader()
{
	fr_stream.close();
}

std::string FileReader::read(unsigned int start, unsigned int end)
{
	fr_stream.seekg(start, std::ios::beg);
	if (fr_stream.eof())
	{
		std::stringstream err_stream;
		err_stream << "read() w FileReader.cpp. Próba odczytu poza plikiem na pozycjach "
				<< start << "-" << end;

		throw std::out_of_range( err_stream.str() );
	}
	char *buf = new char[ end - start + 1 ];
	fr_stream.read(buf, end - start);
	buf[end - start] = '\0';
	std::string str = buf;
	delete [] buf;

	return str;
}

char FileReader::charAt(unsigned int pos)
{
	fr_stream.seekg(pos, std::ios::beg);
	if (fr_stream.eof())
		throw std::out_of_range(
				"charAt() w FileReader.cpp. Próba odczytu poza plikiem na pozycji "
						+ boost::lexical_cast <unsigned int> (pos));
	return fr_stream.peek();
}
